using System;
using System.Collections.Generic;
using Session;
using UnityEngine;

namespace Game.Tile
{
    public static class Utils
    {
        /// <summary>
        ///     获取 或者 创建后获取 TileController 的 TileGroup
        /// </summary>
        /// <param name="targetTileVisual">目标 TileController </param>
        /// <param name="getTileVisualFunc"></param>
        /// <param name="session"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        public static TileGroupVisual GetOrInitTileGroup(TileVisual targetTileVisual, Func<Vector2Int, TileVisual> getTileVisualFunc, ISession session, Transform parent)
        {
            if (targetTileVisual.TileGroupVisual != null) return targetTileVisual.TileGroupVisual;

            // 创建 TileGroup 游戏对象
            var targetGo = new GameObject("TileGroup");
            // 给目标挂载 TileGroup 脚本，并初始化
            var targetTileGroup = targetGo.AddComponent<TileGroupVisual>();
            // 初始化 TileGroup
            targetTileGroup.Setup(getTileVisualFunc, session, parent);
            // 向 TileGroup 注册 TileController
            targetTileGroup.Register(targetTileVisual);
            return targetTileGroup;
        }

        /// <summary>
        ///     获取 Tile 之间的补偿值
        /// </summary>
        /// <param name="direction"></param>
        /// <param name="tileSize"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public static Vector2Int GetTileOffset(Tile.Direction direction, int tileSize)
        {
            var offset = new Vector2Int(0, 0);
            switch (direction)
            {
                case Tile.Direction.Up:
                    offset.y = tileSize;
                    break;
                case Tile.Direction.Down:
                    offset.y = -tileSize;
                    break;
                case Tile.Direction.Left:
                    offset.x = -tileSize;
                    break;
                case Tile.Direction.Right:
                    offset.x = tileSize;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            return offset;
        }

        /// <summary>
        ///     找到当前 Tile 四边的 Tile Index
        /// </summary>
        /// <param name="numTileX">拼图总长度</param>
        /// <param name="numTileY">拼图总高度</param>
        /// <param name="tileIndex">要获取四边拼图块的拼图块索引</param>
        /// <returns></returns>
        public static List<(Tile.Direction, Vector2Int)> GetForeSidesTileControllers(
            int numTileX,
            int numTileY,
            Vector2Int tileIndex)
        {
            var left = new Vector2Int(tileIndex.x - 1, tileIndex.y);
            var right = new Vector2Int(tileIndex.x + 1, tileIndex.y);
            var up = new Vector2Int(tileIndex.x, tileIndex.y + 1);
            var down = new Vector2Int(tileIndex.x, tileIndex.y - 1);

            var sides = new List<(Tile.Direction, Vector2Int)>(4);
            if (_Check(left)) sides.Add((Tile.Direction.Left, left));
            if (_Check(right)) sides.Add((Tile.Direction.Right, right));
            if (_Check(up)) sides.Add((Tile.Direction.Up, up));
            if (_Check(down)) sides.Add((Tile.Direction.Down, down));
            return sides;

            bool _Check(Vector2Int vec)
            {
                return vec is { x: >= 0, y: >= 0 } && vec.x < numTileX && vec.y < numTileY;
            }
        }
    }
}